package com.venmo.view;

import ohos.agp.components.*;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.Path;
import ohos.app.Context;
import ohos.global.resource.NotExistException;
import ohos.global.resource.WrongTypeException;
import java.io.IOException;

public class TooltipView extends Text
        implements Component.EstimateSizeListener, Component.DrawTask {

    private static final int NOT_PRESENT = Integer.MIN_VALUE;
    private int arrowHeight;
    private int arrowWidth;
    private int cornerRadius;
    private int anchoredViewId;
    private int tooltipColor;
    private ArrowLocation arrowLocation;
    private ArrowAlignment arrowAlignment;
    private int alignmentOffset;
    private int arrowPositioning;
    private Paint paint;
    private Path tooltipPath;
    private int width = 0;
    private int height = 0;

    public TooltipView(Context context) {
        this(context, null);
    }

    public TooltipView(Context context, AttrSet attrSet) {
        this(context, attrSet, null);
    }

    public TooltipView(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        init(attrSet);
        setEstimateSizeListener(this);
        addDrawTask(this);
    }

    private void init(AttrSet attrs) {
        if (attrs == null) {
            return;
        }

        try {
            if (attrs.getAttr("anchoredView").isPresent()) {
                anchoredViewId = attrs.getAttr("anchoredView").get().getIntegerValue();
            } else {
                anchoredViewId = Component.ID_DEFAULT;
            }
            if (attrs.getAttr("tooltipColor").isPresent()) {
                tooltipColor = attrs.getAttr("tooltipColor").get().getColorValue().getValue();
            } else {
                tooltipColor = getResourceManager()
                        .getElement(ResourceTable.Color_TRANSPARENT).getColor();
            }
            if (attrs.getAttr("cornerRadius").isPresent()) {
                cornerRadius = attrs.getAttr("cornerRadius").get().getDimensionValue();
            } else {
                cornerRadius = getResourceManager()
                        .getElement(ResourceTable.Integer_tooltip_default_corner_radius).getInteger();
            }
            if (attrs.getAttr("arrowHeight").isPresent()) {
                arrowHeight = attrs.getAttr("arrowHeight").get().getDimensionValue() / 3;
            } else {
                arrowHeight = getResourceManager()
                        .getElement(ResourceTable.Integer_tooltip_default_arrow_height).getInteger();
            }
            if (attrs.getAttr("arrowWidth").isPresent()) {
                arrowWidth = attrs.getAttr("arrowWidth").get().getDimensionValue() / 3;
            } else {
                arrowWidth = getResourceManager()
                        .getElement(ResourceTable.Integer_tooltip_default_arrow_width).getInteger();
            }
            if (attrs.getAttr("arrowPositioning").isPresent()) {
                arrowPositioning = attrs.getAttr("arrowPositioning").get().getIntegerValue();
            } else {
                arrowPositioning = getResourceManager()
                        .getElement(ResourceTable.Integer_tooltip_default_arrow_location).getInteger();
            }
            arrowLocation = arrowPositioning == 0 ? new TopArrowLocation()
                        : new BottomArrowLocation();
            if (attrs.getAttr("arrowAlignment").isPresent()) {
                arrowAlignment = ArrowAlignment
                        .getAlignment(attrs.getAttr("arrowAlignment").get().getIntegerValue());
            } else {
                arrowAlignment = ArrowAlignment
                        .getAlignment(getResourceManager()
                                        .getElement(ResourceTable.Integer_tooltip_default_arrow_alignment).getInteger());
            }
            if (attrs.getAttr("arrowAlignmentOffset").isPresent()) {
                alignmentOffset = attrs.getAttr("arrowAlignmentOffset").get().getIntegerValue();
            } else {
                alignmentOffset = getResourceManager()
                        .getElement(ResourceTable.Integer_tooltip_default_offset).getInteger();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NotExistException e) {
            e.printStackTrace();
        } catch (WrongTypeException e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean onEstimateSize(int widthMeasureSpec, int heightMeasureSpec) {
        int widthSpce = EstimateSpec.getMode(widthMeasureSpec);
        int heightSpce = EstimateSpec.getMode(heightMeasureSpec);

        int widthConfig = 0;
        switch (widthSpce) {
            case EstimateSpec.UNCONSTRAINT:
            case EstimateSpec.PRECISE:
                width = EstimateSpec.getSize(widthMeasureSpec);
                widthConfig = EstimateSpec.getSizeWithMode(width, EstimateSpec.PRECISE);
                break;
            case EstimateSpec.NOT_EXCEED:
                widthConfig = EstimateSpec.getSizeWithMode(width, EstimateSpec.PRECISE);
                break;
            default:
                break;
        }

        int heightConfig = 0;
        switch (heightSpce) {
            case EstimateSpec.UNCONSTRAINT:
            case EstimateSpec.PRECISE:
                height = EstimateSpec.getSize(heightMeasureSpec);
                heightConfig = EstimateSpec.getSizeWithMode(height, EstimateSpec.PRECISE);
                break;
            case EstimateSpec.NOT_EXCEED:
                heightConfig = EstimateSpec.getSizeWithMode(height, EstimateSpec.PRECISE);
                break;
            default:
                break;
        }
        setEstimatedSize(widthConfig, heightConfig + arrowHeight);
        return true;
    }

    @Override
    public void invalidate() {
        super.invalidate();
        tooltipPath = null;
        paint = null;
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        if (tooltipPath == null || paint == null) {
            arrowLocation.configureDraw(this, canvas);
        }
        canvas.drawPath(tooltipPath, paint);
    }

    Paint getTooltipPaint() {
        return paint;
    }

    void setPaint(Paint paint) {
        this.paint = paint;
    }

    Path getTooltipPath() {
        return tooltipPath;
    }

    void setTooltipPath(Path tooltipPath) {
        this.tooltipPath = tooltipPath;
    }

    public int getArrowHeight() {
        return arrowHeight;
    }

    public void setArrowHeight(int arrowHeight) {
        this.arrowHeight = arrowHeight;
        invalidate();
    }

    public void setArrowHeightResource(int resId) {
        try {
            arrowHeight = getResourceManager().getElement(resId).getInteger();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NotExistException e) {
            e.printStackTrace();
        } catch (WrongTypeException e) {
            e.printStackTrace();
        }
        invalidate();
    }

    public int getArrowWidth() {
        return arrowWidth;
    }

    public void setArrowWidth(int arrowWidth) {
        this.arrowWidth = arrowWidth;
        invalidate();
    }

    public void setArrowWidthResource(int resId) {
        try {
            arrowWidth = getResourceManager().getElement(resId).getInteger();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NotExistException e) {
            e.printStackTrace();
        } catch (WrongTypeException e) {
            e.printStackTrace();
        }
        invalidate();
    }

    public int getCornerRadius() {
        return cornerRadius;
    }

    public void setCornerRadius(int cornerRadius) {
        this.cornerRadius = cornerRadius;
        invalidate();
    }

    public void setCornerRadiusResource(int resId) {
        try {
            cornerRadius = getResourceManager().getElement(resId).getInteger();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NotExistException e) {
            e.printStackTrace();
        } catch (WrongTypeException e) {
            e.printStackTrace();
        }
        invalidate();
    }

    public int getAnchoredViewId() {
        return anchoredViewId;
    }

    public void setAnchoredViewId(int anchoredViewId) {
        this.anchoredViewId = anchoredViewId;
        invalidate();
    }

    public int getTooltipColor() {
        return tooltipColor;
    }

    public void setTooltipColor(int tooltipColor) {
        this.tooltipColor = tooltipColor;
        invalidate();
    }

    public void setArrowPositioning(int arrowPositioning) {
        this.arrowPositioning = arrowPositioning;
        invalidate();
    }

    public ArrowAlignment getArrowAlignment() {
        return arrowAlignment;
    }

    public void setArrowAlignment(ArrowAlignment arrowAlignment) {
        this.arrowAlignment = arrowAlignment;
        invalidate();
    }

    public int getAlignmentOffset() {
        return alignmentOffset;
    }

    public void setAlignmentOffset(int offset) {
        this.alignmentOffset = offset;
        invalidate();
    }

    public void setAlignmentOffsetResource(int resId) {
        try {
            this.alignmentOffset = getResourceManager().getElement(resId).getInteger();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NotExistException e) {
            e.printStackTrace();
        } catch (WrongTypeException e) {
            e.printStackTrace();
        }
        invalidate();
    }
}
